//
// Created by 11510 on 2024/6/14.
//

#include "CowString.h"

/**
 * 重载输出流
 * @param os
 * @param rhs
 * @return
 */
ostream& operator<<(ostream& os, const CowString& rhs){
    os << rhs._pstr;
    return os;
}


/**
 * 无参构造
 */
CowString::CowString(){
    /**
     * 4B存放引用计数
     * 1B存放null
     */
    _pstr = malloc_fake();
    initRefCnt();
    cout << "constructor" << endl;
}


/**
 * 析构
 */
CowString::~CowString(){
    release();
}

/**
 * 拷贝构造
 * @param rhs
 */
CowString::CowString(const CowString& rhs) {
    /* 浅拷贝 */
    _pstr = rhs._pstr;
    increaseRefCnt();
    cout << "copy constructor" << endl;
}

/**
 * c风格有参构造
 * @param pstr
 */
CowString::CowString(const char *pstr):_pstr(malloc_fake(pstr)) {
    initRefCnt();
    strcpy(_pstr, pstr);
    cout << "char* constructor" << endl;
}

/**
 * 重载赋值运算符
 * @param rhs
 * @return
 */
CowString& CowString::operator=(const CowString& rhs){
    if (this != &rhs){  /* 自赋值 */
        release();  /* 尝试回收 */
        _pstr = rhs._pstr;   /* 浅拷贝 */
        increaseRefCnt();   /* 引用计数加一 */
    }
    return *this;
}

/**
 * CharProxy 对象保存一个下标和一个引用向上绑定str1
 * @param index
 * @return
 */
CowString::CharProxy CowString::operator[](int index){
    return CharProxy(*this, index);
}

char CowString::CharProxy::operator=(char ch) {
    if(_idx >= 0 && _idx < _self.size()){
        if(_self.useCount() > 1){
            /* 原来的引用计数-1*/
            _self.decreaseRefCnt();
            /* 深拷贝 */
            char* ptemp = _self.malloc_fake(_self._pstr);
            strcpy(ptemp, _self._pstr);
            /* 修改指向 */
            _self._pstr = ptemp;
            /* 新的空间，初始化引用计数 */
            _self.initRefCnt();
        }

        /* 执行写操作 */
        _self._pstr[_idx] = ch;
        return _self._pstr[_idx];
    }
    cerr << "out of range" << endl;
    /**
     * 返回引用时必须要加static
     */
    static char nullchar = '\0';
    return nullchar;
}

// 删除重载输出流
//ostream& operator<<(ostream& os, const CowString::CharProxy & rhs){
//    if(rhs._idx >= 0 && rhs._idx < rhs._self.size()){
//        os << rhs._self._pstr[rhs._idx];
//    }else{
//        os << "out of range" << endl;
//    }
//    return os;
//}

// 补充:输出流运算符自带转换字符串效果，所以自带强转效果
/*
 * template <class _Traits>inline basic_ostream<char, _Traits>&
 * operator<<(basic_ostream<char, _Traits>& __out, char __c){
 *     return __ostream_insert(__out, &__c, 1);
 * }
 *
 */